﻿using DAL.Repositories;
using EntitiesLayer;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
using DAL.AbstractRepositories;
using DAL.RepositoryInterfaces;

namespace DAL.Repositorios
{
    public class EjercicioRepository : DAL.AbstractRepositories.AbstractRepository<Ejercicio>, DAL.RepositoryInterfaces.IRandomReposiotry<Ejercicio>
    {
       
        public override void Insert(Ejercicio entity)
        {
            Inserted.Add(entity);
        }

        public override void Delete(Ejercicio entity)
        {
            Deleted.Add(entity);
        }

        public override void Update(Ejercicio entity)
        {
            Updated.Add(entity);
        }

        public override IEnumerable<Ejercicio> GetAll()
        {
            IList<Ejercicio> lista = new List<Ejercicio>();
            SqlCommand cmd = new SqlCommand();
            DataSet ds = DBAccess.ExecuteSPWithDS(ref cmd, "PaListarEjercicios");

            foreach (DataRow dr in ds.Tables[0].Rows)
                lista.Add(crearEjercicio(dr.Field<int>("Ejercicios_ID"), dr));

            return lista.Count > 0 ? lista : null;
        }

        public override Ejercicio GetById(int id)
        {
            Ejercicio ejercicio = null;
            SqlCommand cmd = new SqlCommand();
            cmd.Parameters.Add(new SqlParameter("@IdEjercicio", id));
            DataSet ds = DBAccess.ExecuteSPWithDS(ref cmd, "PaConsultarEjercicioPorID");

            foreach (DataRow dr in ds.Tables[0].Rows)
                 ejercicio= crearEjercicio(id, dr);

            return ejercicio;
        }

        internal Ejercicio crearEjercicio(int id, DataRow dr)
        {
            MusculoRepository mrepo= (MusculoRepository)UnitOfWork.RepositoryMusculo;
            ImagenRepository irepo=  (ImagenRepository)UnitOfWork.RepositoryImagenes;

            return new Ejercicio(
                 
                pnombre: dr["Nombre"].ToString(),
                pnombre2: dr["SegundoNombre"].ToString(),
                pposini:dr["PosInicial"].ToString(),
                pposfin: dr["PosFinal"].ToString(),
                pindicaciones: dr["Indicaciones"].ToString(),
                perrores: dr["Errores"].ToString(),
                pid: id, 
                musculosPrimarios: new Lazy<IList<Musculos>>(
                    ()=>mrepo.musculosPEjercicio(id)
                ),

                musculosSecundarios: new Lazy<IList<Musculos>>(
                    () => mrepo.musculosSEjercicio(id)
                ),
                listaImagenes: new Lazy<IList<Imagen>>(
                    () => irepo.imagenDeEjercicio(id)
                )
 
            );
             
        }


        protected override void DeleteEntity(Ejercicio le)
        {
            SqlCommand cmd = new SqlCommand();
            cmd.Parameters.Add(new SqlParameter("@IdEjercicio", le.Id));
            DataSet ds = DBAccess.ExecuteSPWithDS(ref cmd, "PaEliminarEjercicio");
        }

        protected override void UpdateEntity(Ejercicio le)
        {
          
                SqlCommand cmd = new SqlCommand();
                cmd.Parameters.Add(new SqlParameter("@pIdEjercicio", le.Id));
                cmd.Parameters.Add(new SqlParameter("@pNombre", le.Nombre));
                cmd.Parameters.Add(new SqlParameter("@pSegundo", le.Segundonombre));
                cmd.Parameters.Add(new SqlParameter("@pPosIni", le.PosInicial));
                cmd.Parameters.Add(new SqlParameter("@pPosFin", le.PosFinal));
                cmd.Parameters.Add(new SqlParameter("@pIndica", le.Indicaciones));
                cmd.Parameters.Add(new SqlParameter("@pErrores", le.Errores));



                DBAccess.ExecuteSPNonQuery(ref cmd, "PaModificarEjercicio");
           
        }

        protected override void InsertEntity(Ejercicio le)
        {
                SqlCommand cmd = new SqlCommand();
                cmd.Parameters.Add(new SqlParameter("@pNombre", le.Nombre));
                cmd.Parameters.Add(new SqlParameter("@pSegundo", le.Segundonombre));
                cmd.Parameters.Add(new SqlParameter("@pPosIni", le.PosInicial));
                cmd.Parameters.Add(new SqlParameter("@pPosFin", le.PosFinal));
                cmd.Parameters.Add(new SqlParameter("@pIndica", le.Indicaciones));
                cmd.Parameters.Add(new SqlParameter("@pErrores", le.Errores));

                long idAuto=DBAccess.ExecuteSPScalar(ref cmd, "PaRegistrarEjercicio");

                this.IdAutoGenerados.Add(le,idAuto);
              
        }


        public IList<Ejercicio> getRandoms()
        {
            SqlCommand cmd = new SqlCommand();

            DataSet ds = DBAccess.ExecuteSPWithDS(ref cmd, "PaEjerciciosAgrupados");

            DataRowCollection Cdr= ds.Tables[0].Rows;

            IDictionary<int,Ejercicio> currentEjercicios = new Dictionary<int,Ejercicio>();

            HashSet<int> intentos = new HashSet<int>();
            
            for (int j=0; (j<Cdr.Count);)
            {
                int cantidad = Cdr[j].Field<int>("cantidad");
                int numeroAleatorio = new Random().Next(cantidad) + j;
                
                int id = Cdr[numeroAleatorio].Field<int>("Ejercicios_ID");
                bool containsId = currentEjercicios.ContainsKey(id);
                
                if (containsId)
                     intentos.Add(numeroAleatorio);
                else
                    currentEjercicios.Add(id, crearEjercicio(id, Cdr[numeroAleatorio]));
                   

                if (intentos.Count == cantidad || !containsId)
                {
                    intentos.Clear();
                    j += cantidad;
                }
               
            }

            return currentEjercicios.Values.ToList();


        }
    }
}
